#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <cstdlib>
#include <ctime>

// 共享资源
int shared_data = 0;

// 读写锁
pthread_rwlock_t rwlock;

// 读者线程函数
void *reader(void *arg) {
    // 读者优先，一旦很多读者进入，就会有写者饥饿
    int id = *(int*)arg;
    while(true) {
        pthread_rwlock_rdlock(&rwlock); // 读者加锁
        std::cout << "读者-" << id << "正在读取数据，数据是: " << shared_data << std::endl;
        pthread_rwlock_unlock(&rwlock); // 读者解锁

        sleep(1); // 模拟读者 在非共享区间的操作
    }

    delete (int*)arg;
    return nullptr;
}

// 写者线程函数
void *writer(void *arg) {
    int id = *(int*)arg;
    while(true) {
        pthread_rwlock_wrlock(&rwlock); // 写者加锁
        shared_data = rand() % 100; // 修改共享数据
        std::cout << "写者-" << id << "正在写入，新的数据是: " << shared_data << std::endl;
        sleep(2);
        pthread_rwlock_unlock(&rwlock);
    }

    delete (int*)arg;
    return nullptr;
}

int main() {
    srand((unsigned int)time(nullptr));
    pthread_rwlock_init(&rwlock, nullptr); // 初始化读写锁

    const int reader_num = 2;
    const int writer_num = 5;
    const int total = reader_num + writer_num;
    pthread_t threads[total];

    // 创建写者线程
    for(int i = 0; i < writer_num; ++i) {
        int *id = new int(i);
        pthread_create(&threads[i], nullptr, writer, id);
    }

    // 创建读者线程
    for(int i = writer_num; i < total; ++i) {
        int *id = new int(i - writer_num);
        pthread_create(&threads[i], nullptr, reader, id);
    }

    // 等待所有线程完成
    for(int i = 0; i < total; ++i) 
        pthread_join(threads[i], nullptr);
    
    // 销毁读写锁
    pthread_rwlock_destroy(&rwlock);

    return 0;
}